﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Threading;
using Microsoft.Xna.Framework.Content;

namespace Ivory
{
    public abstract class GameScreen : Screenbase {
        //Fields
        private bool isLoaded = false;
        protected LoadScreenBase LoadingScreen;

        //Construct
        public GameScreen(Game game)
            : base(game)
        {
            isLoaded = false; //The game isnt Loaded by default, must be forced
            LoadingScreen = null;
        }

        //Methods
        #region #@@ Drawing @@#
        public override void drawScreen(SpriteBatch batch, GameTime time)
        {
            if (isLoaded) {                
                //Render Game
                RenderGame(batch, time);
                RenderUI(batch, time);
            }
            else {
                if (LoadingScreen == null)
                    throw new Exception("Firefly Error #007 : Loading screen is not present, all game screens require a loading screen");
                
                LoadingScreen.drawScreen(batch, time);
            }
        }

        public abstract void RenderGame(SpriteBatch batch, GameTime time);
        public abstract void RenderUI(SpriteBatch batch, GameTime time);
        
        #endregion

        #region #@@ Updating @@#
        public override void updateScreen(GameTime time)
        {
            if (isLoaded) {
                //Update the game logic.
                UpdateGame(time);
                UpdateUI(time);                
            }
            else {
                if (LoadingScreen == null)
                    throw new Exception("Firefly Error #007 : Loading screen is not present, all game screens require a loading screen");

                LoadingScreen.updateScreen(time);
            }
        }

        public abstract void UpdateGame(GameTime time);
        public abstract void UpdateUI(GameTime time);

        #endregion

        #region #@@ Loading @@#
        public override void loadScreen(ContentManager manager)
        {
            //If we get here, we need to re/load
            //Toggle loadScreen on & wait for its signal
            isLoaded = false;
            Thread loadingThread = new Thread(new ThreadStart(trumpAssets));
            loadingThread.Join();
            loadingThread.Start();
        }
        public override void preLoad(ContentManager content)
        {
            LoadAssets();
        }

        private void trumpAssets()
        {
            //using trumpAssets allows us to keep the laod screen going, untill we have finished loading
            //Call LoadAssets() to load data into the game
            if (LoadLogic())
                this.isLoaded = true;
            else //If we didnt load properly, report an error #001
                throw new Exception("Firefly Error #001: Error loading into the game");
        }
        public void unload()
        {
            isLoaded = false;
        }

        /// <summary>
        /// Assets are preloaded, logic is loaded on Load screen
        /// </summary>
        /// <returns></returns>
        public abstract bool LoadAssets();
        public abstract bool LoadLogic();

        #endregion

    }
}
